/*     */ package com.zimbra.qa.unittest;
/*     */ 
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.db.AbstractRetry;
/*     */ import com.zimbra.cs.db.DbPool;
/*     */ import com.zimbra.cs.db.RetryConnectionFactory;
/*     */ import com.zimbra.cs.db.SQLite;
/*     */ import java.sql.Connection;
/*     */ import java.sql.PreparedStatement;
/*     */ import java.sql.ResultSet;
/*     */ import java.sql.SQLException;
/*     */ import junit.framework.TestCase;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class TestSQLiteBusyHandler
/*     */   extends TestCase
/*     */ {
/*     */   public static final int timeout = 120000;
/*  44 */   private final Log log = ZimbraLog.test;
/*     */   private static final String DB_PATH = "data/unittest/sqlite/";
/*     */   
/*     */   public Connection createConnect() throws Exception
/*     */   {
/*  49 */     Class.forName("org.sqlite.JDBC");
/*  50 */     RetryConnectionFactory factory = new RetryConnectionFactory("jdbc:sqlite:data/unittest/sqlite/zimbra.db", null);
/*  51 */     return factory.createConnection();
/*     */   }
/*     */   
/*     */   public String getDatabaseFilename(String dbname) {
/*  55 */     return "data/unittest/sqlite/" + dbname + ".db";
/*     */   }
/*     */   
/*     */   void attachDatabase(Connection conn, String dbname) throws SQLException, ServiceException {
/*  59 */     PreparedStatement stmt = null;
/*     */     try
/*     */     {
/*  62 */       boolean autocommit = conn.getAutoCommit();
/*  63 */       if (!autocommit) {
/*  64 */         conn.setAutoCommit(true);
/*     */       }
/*  66 */       (stmt = conn.prepareStatement("ATTACH DATABASE \"" + getDatabaseFilename(dbname) + "\" AS " + dbname)).execute();
/*  67 */       this.log.debug("********************* attached %s", new Object[] { dbname });
/*     */     } catch (SQLException e) {
/*  69 */       this.log.error("database " + dbname + " attach failed", e);
/*  70 */       if (!"database is already attached".equals(e.getMessage()))
/*  71 */         throw e;
/*     */     } finally {
/*  73 */       DbPool.quietCloseStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   void detachDatabase(Connection conn, String dbname) throws SQLException
/*     */   {
/*  79 */     PreparedStatement stmt = null;
/*     */     try {
/*  81 */       boolean autocommit = conn.getAutoCommit();
/*  82 */       if (!autocommit) {
/*  83 */         conn.setAutoCommit(true);
/*     */       }
/*  85 */       (stmt = conn.prepareStatement("DETACH DATABASE " + dbname)).execute();
/*  86 */       this.log.debug("detached %s", new Object[] { dbname });
/*     */     } catch (SQLException e) {
/*  88 */       this.log.error("database " + dbname + " attach failed", e);
/*  89 */       if (!"database is already attached".equals(e.getMessage()))
/*  90 */         throw e;
/*     */     } finally {
/*  92 */       DbPool.quietCloseStatement(stmt);
/*     */     }
/*     */   }
/*     */   
/*     */   public Connection connectAndAttach(String dbName) throws SQLException, ServiceException, Exception
/*     */   {
/*  98 */     Connection conn = createConnect();
/*  99 */     attachDatabase(conn, dbName);
/* 100 */     return conn;
/*     */   }
/*     */   
/*     */   public boolean checkSubject(String subject, String dbName, Connection conn) throws Exception {
/* 104 */     PreparedStatement stmt = conn.prepareStatement("select subject from " + dbName + ".mail_item where subject='" + subject + "'");
/* 105 */     ResultSet rs = stmt.executeQuery();
/*     */     try {
/* 107 */       if (!rs.next()) {
/* 108 */         throw new Exception("no rows returned with subject [" + subject + "]");
/*     */       }
/* 110 */       if (rs.next()) {
/* 111 */         throw new Exception("multiple rows returned with subject [" + subject + "]");
/*     */       }
/*     */       
/* 114 */       this.log.debug("check subject OK");
/* 115 */       return true;
/*     */     } finally {
/* 117 */       rs.close();
/* 118 */       stmt.close();
/*     */     }
/*     */   }
/*     */   
/*     */   public void testUpdate(String dbName, Connection conn) throws Exception {
/* 123 */     PreparedStatement stmt = conn.prepareStatement("update " + dbName + ".mail_item set subject='msg123' where subject='msg'");
/* 124 */     stmt.executeUpdate();
/* 125 */     stmt.close();
/* 126 */     checkSubject("msg123", dbName, conn);
/* 127 */     stmt = conn.prepareStatement("update " + dbName + ".mail_item set subject='msg' where subject='msg123'");
/* 128 */     stmt.executeUpdate();
/* 129 */     stmt.close();
/* 130 */     checkSubject("msg", dbName, conn);
/* 131 */     this.log.debug("updated: %s", new Object[] { dbName });
/* 132 */     conn.commit();
/*     */   }
/*     */   
/*     */   public boolean testEntryName(String name, Connection conn) throws Exception {
/* 136 */     PreparedStatement stmt = conn.prepareStatement("select entry_name from directory where entry_id=2");
/* 137 */     ResultSet rs = stmt.executeQuery();
/*     */     try {
/* 139 */       if (!rs.next()) {
/* 140 */         throw new Exception("no rows returned for entry_id 2");
/*     */       }
/* 142 */       String checkName = rs.getString(1);
/* 143 */       if ((checkName == null) || (!checkName.equals(name))) {
/* 144 */         throw new Exception("expected [" + name + "] != db [" + checkName + "]");
/*     */       }
/*     */       
/* 147 */       this.log.debug("check entry OK");
/* 148 */       return 1;
/*     */     } finally {
/* 150 */       rs.close();
/* 151 */       stmt.close();
/*     */     }
/*     */   }
/*     */   
/*     */   public void testUpdateZimbra(Connection conn) throws Exception
/*     */   {
/* 157 */     PreparedStatement stmt = conn.prepareStatement("update directory set entry_name='blah' where entry_id=2");
/* 158 */     stmt.executeUpdate();
/* 159 */     stmt.close();
/* 160 */     testEntryName("blah", conn);
/* 161 */     stmt = conn.prepareStatement("update directory set entry_name='default' where entry_id=2");
/* 162 */     stmt.executeUpdate();
/* 163 */     stmt.close();
/* 164 */     testEntryName("default", conn);
/* 165 */     this.log.debug("updated: zimbra");
/* 166 */     conn.commit();
/*     */   }
/*     */   
/*     */   public void testSelectZimbra(Connection conn) throws Exception
/*     */   {
/* 171 */     PreparedStatement ps = conn.prepareStatement("select * from directory");
/* 172 */     ResultSet rs = ps.executeQuery();
/* 173 */     rs.close();
/* 174 */     ps.close();
/* 175 */     this.log.debug("read: zimbra");
/*     */   }
/*     */   
/*     */   public void integrityCheck(Connection conn, String dbname) throws Exception {
/* 179 */     PreparedStatement stmt = null;
/* 180 */     String prefix = dbname + ".";
/* 181 */     stmt = conn.prepareStatement("PRAGMA " + prefix + "integrity_check");
/* 182 */     stmt.execute();
/* 183 */     ResultSet rs = stmt.getResultSet();
/*     */     try {
/* 185 */       if (rs.next()) {
/* 186 */         String resp = rs.getString(1);
/* 187 */         if (resp.equals("ok")) {
/* 188 */           this.log.debug("integrity check ok"); return;
/*     */         }
/*     */       }
/*     */       
/* 192 */       throw new Exception("Integrity Check Failed");
/*     */     } finally {
/* 194 */       rs.close();
/* 195 */       stmt.close();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/* 200 */   public static boolean error = false;
/* 201 */   public static boolean timedOut = false;
/*     */   
/*     */   public void testNoBusy()
/*     */   {
/* 205 */     LC.zimbra_class_database.setDefault(SQLite.class.getName());
/*     */     try {
/* 207 */       Thread t = new Thread("Update Zimbra") {
/*     */         public void run() {
/*     */           try {
/* 210 */             Connection conn1 = TestSQLiteBusyHandler.this.createConnect();
/* 211 */             conn1.setAutoCommit(false);
/* 212 */             while ((!TestSQLiteBusyHandler.error) && (!TestSQLiteBusyHandler.timedOut)) {
/* 213 */               TestSQLiteBusyHandler.this.testUpdateZimbra(conn1);
/*     */             }
/*     */           } catch (Exception e) {
/* 216 */             TestSQLiteBusyHandler.error = true;
/* 217 */             TestSQLiteBusyHandler.this.log.error("Exception in thread", e);
/*     */           }
/*     */         }
/* 220 */       };
/* 221 */       t.start();
/*     */       
/* 223 */       Thread t2 = new Thread("Attach Test2") {
/*     */         public void run() {
/*     */           try {
/* 226 */             Connection conn2 = TestSQLiteBusyHandler.this.createConnect();
/* 227 */             while ((!TestSQLiteBusyHandler.error) && (!TestSQLiteBusyHandler.timedOut)) {
/* 228 */               TestSQLiteBusyHandler.this.attachDatabase(conn2, "test2");
/* 229 */               TestSQLiteBusyHandler.this.detachDatabase(conn2, "test2");
/*     */             }
/*     */           } catch (Exception e) {
/* 232 */             TestSQLiteBusyHandler.error = true;
/* 233 */             TestSQLiteBusyHandler.this.log.error("Exception in thread", e);
/*     */           }
/*     */         }
/* 236 */       };
/* 237 */       t2.start();
/*     */       
/* 239 */       Thread t3 = new Thread("Update Test1") {
/*     */         public void run() {
/*     */           try {
/* 242 */             Connection conn3 = TestSQLiteBusyHandler.this.connectAndAttach("test1");
/* 243 */             TestSQLiteBusyHandler.this.attachDatabase(conn3, "test2");
/* 244 */             conn3.setAutoCommit(false);
/* 245 */             while ((!TestSQLiteBusyHandler.error) && (!TestSQLiteBusyHandler.timedOut)) {
/* 246 */               TestSQLiteBusyHandler.this.testUpdate("test1", conn3);
/*     */             }
/*     */           } catch (Exception e) {
/* 249 */             TestSQLiteBusyHandler.error = true;
/* 250 */             TestSQLiteBusyHandler.this.log.error("Exception in thread", e);
/*     */           }
/*     */         }
/* 253 */       };
/* 254 */       t3.start();
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 276 */       Thread t5 = new Thread("Connection test") {
/*     */         public void run() {
/*     */           try {
/* 279 */             while ((!TestSQLiteBusyHandler.error) && (!TestSQLiteBusyHandler.timedOut)) {
/* 280 */               Connection conn5 = TestSQLiteBusyHandler.this.createConnect();
/* 281 */               conn5.close();
/*     */             }
/*     */           } catch (Exception e) {
/* 284 */             TestSQLiteBusyHandler.error = true;
/* 285 */             TestSQLiteBusyHandler.this.log.error("Exception in thread", e);
/*     */           }
/*     */         }
/* 288 */       };
/* 289 */       t5.start();
/*     */       
/* 291 */       Thread timeoutThread = new Thread("Timeout") {
/*     */         public void run() {
/*     */           try {
/* 294 */             TestSQLiteBusyHandler.this.log.info("running for 120000ms");
/* 295 */             Thread.sleep(120000L);
/* 296 */             TestSQLiteBusyHandler.timedOut = true;
/*     */ 
/*     */           }
/*     */           catch (InterruptedException e) {}
/*     */         }
/* 301 */       };
/* 302 */       timeoutThread.start();
/* 303 */       boolean joined = false;
/* 304 */       while ((!error) && (!joined)) {
/* 305 */         timeoutThread.join(1000L);
/* 306 */         if (!timeoutThread.isAlive()) {
/* 307 */           joined = true;
/*     */         }
/*     */       }
/*     */     }
/*     */     catch (Exception e) {
/* 312 */       this.log.error("Exception", e);
/* 313 */       error = true;
/*     */     }
/*     */     
/* 316 */     if (error) {
/* 317 */       fail();
/*     */     } else {
/* 319 */       this.log.info("ran for 120000ms with no exceptions.");
/* 320 */       this.log.info("Encountered [" + AbstractRetry.getTotalRetries() + "] busy retries");
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/qa/unittest/TestSQLiteBusyHandler.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */